#!/usr/bin/python2.7
#coding:UTF-8
 
'''
Created on 19 апр. 2014 г.

@author: nww
'''
import threading
#import time
#from numpy import arange, sin, pi
import wx
from wx.lib.pubsub import  Publisher
import select
import socket
import sys

class TCP_server(threading.Thread):
    '''threading.Thread
    classdocs
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self.exitFlag = False
        threading.Thread.__init__(self)
        
    def run(self):
        ''' Переопределяем унаследованный от threading.Thread метод run()
        для выполнения в нём TCP сервера
        '''

        # Create a TCP/IP socket
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.setblocking(0)

        # Bind the socket to the port
        server_address = ('localhost', 10000)
        print >>sys.stderr, 'starting up on %s port %s' % server_address
        server.bind(server_address)

        # Listen for incoming connections
        server.listen(5)

        # Sockets from which we expect to read
        inputs = [ server ]

        # Sockets to which we expect to write
        outputs = [ ]

        while not self.exitFlag:
            
            # Wait for at least one of the sockets to be ready for processing
            print >>sys.stderr, '\nwaiting for the next event'
            readable, writable, exceptional = select.select(inputs, outputs, inputs)

            # Handle inputs
            for s in readable:

                if s is server:
                    # A "readable" server socket is ready to accept a connection
                    connection, client_address = s.accept()
                    print >>sys.stderr, 'new connection from', client_address
                    connection.setblocking(0)
                    inputs.append(connection)

                else:
                    data = s.recv(1048576)
                    if data:
                        # A readable client socket has data
#                        print >>sys.stderr, 'received "%s" from %s' % (data, s.getpeername())
#                        print >>sys.stderr, 'received data from %s' % (s.getpeername())
#                        message_queues[s].put(data)
                        # Планируем вызов функции postData в цикле обработки GUI
                        wx.CallAfter(self.postData, range(len(data)), [ord(i) for i in data])
                        # Add output channel for response
#                        if s not in outputs:
#                            outputs.append(s)

                    else:
                        # Interpret empty result as closed connection
                        print >>sys.stderr, 'closing', client_address, 'after reading no data'
                        # Stop listening for input on the connection
                        if s in outputs:
                            outputs.remove(s)
                        inputs.remove(s)
                        s.close()

            # Handle outputs
            for s in writable:
                try:
                    pass
#                    next_msg = message_queues[s].get_nowait()
#                except Queue.Empty:
#                    # No messages waiting so stop checking for writability.
#                    print >>sys.stderr, 'output queue for', s.getpeername(), 'is empty'
#                    outputs.remove(s)
#                else:
#                    print >>sys.stderr, 'sending "%s" to %s' % (next_msg, s.getpeername())
#                    s.send(next_msg)
                except:
                    pass

            # Handle "exceptional conditions"
            for s in exceptional:
                print >>sys.stderr, 'handling exceptional condition for', s.getpeername()
                # Stop listening for input on the connection
                inputs.remove(s)
                if s in outputs:
                    outputs.remove(s)
                s.close()

#        print 'TCP server started.'
#        self.t = arange(0.0,3.0,0.01)
#        self.i = 0
#        while not self.exitFlag:
#            self.s = sin(2*pi*self.t+self.i)
#            self.i += 0.05
#            # Планируем вызов функции postData в цикле обработки GUI
#            wx.CallAfter(self.postData, self.t, self.s)
#            time.sleep(0.3)# Чаще нельзя. Глючит интерфейс. По видимому зависит от производительночти компьютера.
#        print 'TCP server stoped.'
        
    def postData(self, t, s):
        Publisher().sendMessage('update', (t, s))
        